/**
 * DroperCom - 纯js下拉菜单组件
 */

class DroperMenuCom {
    static EVENT_CHANGE = "change";
    /**
     * 构造函数
     * @param {HTMLElement} element - 组件挂载的元素
     * @param {Object} options - 组件配置选项
     */
    constructor(element, options = {}) {
        // 默认配置
        this.options = {
            theme: "#409EFF",        // 主题样式 
            size: "medium",          // 组件大小 medium | small | large
            creatable: false,        // 是否可创建新项 
            createText: "创建新组",   // 创建新项文本 
            createIcon: "floder-plus", // 创建新项图标class 
            showIcon: true,           // 是否显示图标
            itemIcon: "icon-color",  // 项图标class
            itemText: "颜色组",       // 项文本 
            placeholder: "请选择颜色组", // 占位符 
            width: "100%",           // 宽度 
            name: "groupSelect",     // 组件名称 
            id: "",                  // 组件id 
            editable: true,          // 是否可编辑 
            editText: "编辑名称",     // 编辑文本 
            delable: true,           // 是否可删除 
            delText: "删除分组",      // 删除文本 
            showArrow: true,         // 是否显示下拉箭头 
            placement: "bottom",     // 下拉菜单位置 
            offset: { x: 0, y: 0 },  // 下拉菜单偏移量 
            changeHandler: null,     // 选择改变事件处理函数 
            data: []                 // 菜单数据 {value: "1", text: "颜色组1" ,data:[]}
        };

        // 合并用户配置
        Object.assign(this.options, options);

        // 组件状态
        this.element = element;
        this.isOpen = false;
        this.events = {};

        // 初始化选中值
        this.selectedValue = undefined;

        // 初始化组件
        this._init();
    }

    /**
     * 应用主题色
     */
    _applyTheme() {
        // 如果已经有触发器，应用主题色
        if (this.trigger) {
            // 保存主题色到组件实例，供其他地方使用
            this.themeColor = this.options.theme || "#409EFF";
        }
    }
    
    /**
     * 应用主题色到选中项
     */
    _applyThemeToSelected() {
        // 获取当前选中的值
        const currentValue = this.selectedValue;
        
        if (currentValue !== undefined) {
            // 查找对应的菜单项
            const menuItem = this.menu.querySelector(`.droper-menu-item[data-value="${currentValue}"]`);
            if (menuItem) {
                // 移除之前的选中样式
                const previousSelected = this.menu.querySelector('.droper-menu-item-selected');
                if (previousSelected) {
                    previousSelected.classList.remove('droper-menu-item-selected');
                    previousSelected.style.removeProperty('--theme-color');
                }
                
                // 添加选中样式并应用主题色
                menuItem.classList.add('droper-menu-item-selected');
                menuItem.style.setProperty('--theme-color', this.themeColor || this.options.theme || "#409EFF");
            }
        }
    }

    /**
     * 生成唯一的value值
     * @returns {string} 唯一的value值
     */
    _generateUniqueValue() {
        let uniqueValue;
        let isUnique = false;
        
        // 循环生成直到找到唯一的value值
        while (!isUnique) {
            uniqueValue = 'value_' + Date.now() + '_' + Math.floor(Math.random() * 10000);
            isUnique = !this._isValueExists(uniqueValue);
        }
        
        return uniqueValue;
    }
    
    /**
     * 检查value值是否已存在
     * @param {string} value - 要检查的value值
     * @returns {boolean} 如果value已存在返回true，否则返回false
     */
    _isValueExists(value) {
        return this.options.data.some(item => item.value === value);
    }

    /**
     * 初始化组件
     */
    _init() {
        // 创建组件DOM结构
        this._render();

        // 绑定事件
        this._bindEvents();

        // 设置初始数据
        this.setItems(this.options.data);
    }

    /**
     * 渲染组件
     */
    _render() {
        // 设置组件容器样式
        this.element.className = `droper-container droper-container-${this.options.size}`;
        this.element.style.width = this.options.width;

        // 创建触发器
        this.trigger = document.createElement('div');
        this.trigger.className = `droper-trigger droper-trigger-${this.options.size}`;
        this.trigger.innerHTML = `
            <i class="${this.options.showIcon ? this.options.itemIcon : ''} "></i>
            <span class="droper-placeholder">${this.options.placeholder}</span>
            ${this.options.showArrow ? '<i class="droper-arrow iconfont icon-arrow-down"></i>' : ''}
        `;
        
        // 应用主题色到触发器
        this._applyTheme();

        // 创建菜单
        this.menu = document.createElement('div');
        this.menu.className = 'droper-menu';

        // 添加到容器
        this.element.appendChild(this.trigger);
        this.element.appendChild(this.menu);
    }

    /**
     * 绑定事件
     */
    _bindEvents() {
        // 触发器点击事件
        this.trigger.addEventListener('click', (e) => {
            e.stopPropagation();
            this.toggle();
        });

        // 菜单项点击事件
        this.menu.addEventListener('click', (e) => {
            // 如果点击的是编辑输入框，阻止事件冒泡并直接返回
            if (e.target.classList.contains('droper-edit-input')) {
                e.stopPropagation();
                return;
            }
            
            // 处理编辑按钮点击（包括新面板中的编辑按钮）
            const editBtn = e.target.closest('.droper-item-edit-btn');
            if (editBtn) {
                const index = parseInt(editBtn.dataset.index);
                if (!isNaN(index)) {
                    this.editItem(index);
                }
                e.stopPropagation();
                return;
            }

            // 处理删除按钮点击（包括新面板中的删除按钮）
            const deleteBtn = e.target.closest('.droper-item-delete-btn');
            if (deleteBtn) {
                const index = parseInt(deleteBtn.dataset.index);
                if (!isNaN(index)) {
                    this.removeItem(index);
                }
                e.stopPropagation();
                return;
            }

            // 处理确认编辑按钮点击
            const confirmBtn = e.target.closest('.droper-edit-confirm');
            if (confirmBtn) {
                const index = parseInt(confirmBtn.dataset.index);
                if (!isNaN(index)) {
                    this._confirmEdit(index);
                }
                e.stopPropagation();
                return;
            }

            // 处理取消编辑按钮点击
            const cancelBtn = e.target.closest('.droper-edit-cancel');
            if (cancelBtn) {
                const index = parseInt(cancelBtn.dataset.index);
                if (!isNaN(index)) {
                    this._cancelEdit(index);
                }
                e.stopPropagation();
                return;
            }

            // 处理菜单项点击
            const itemElement = e.target.closest('.droper-menu-item');
            if (itemElement) {
                const index = parseInt(itemElement.dataset.index);
                if (!isNaN(index)) {
                    // 如果是默认创建项
                    if (index === -1) {
                        this._handleCreateItem(e);
                    } else {
                        this._handleItemClick(index, e);
                    }
                }
            }
        });

        // 添加一个变量来存储当前显示的编辑面板和相关状态
        let currentEditPanel = null;
        let currentIconIndex = null;
        let panelHovered = false;
        let iconHovered = false;
        let hidePanelTimer = null;

        // 处理图标悬停显示编辑面板
        this.menu.addEventListener('mouseover', (e) => {
            const iconElement = e.target.closest('.droper-item-icon');
            if (iconElement) {
                const index = parseInt(iconElement.dataset.index);
                if (!isNaN(index)) {
                    // 清除隐藏面板的定时器
                    if (hidePanelTimer) {
                        clearTimeout(hidePanelTimer);
                        hidePanelTimer = null;
                    }
                    
                    iconHovered = true;
                    
                    // 如果已有面板且是同一个图标，不需要重新创建
                    if (currentEditPanel && currentEditPanel.dataset.index === index.toString()) {
                        return;
                    }
                    
                    // 移除已存在的编辑面板
                    if (currentEditPanel) {
                        currentEditPanel.remove();
                        currentEditPanel = null;
                    }
                    
                    // 保存当前图标索引
                    currentIconIndex = index;
                    
                    // 动态创建编辑面板
                    const editPanel = document.createElement('div');
                    editPanel.className = 'droper-edit-panel';
                    editPanel.dataset.index = index;
                    editPanel.innerHTML = `
                        ${this.options.editable ? `<button class="droper-item-edit-btn" data-index="${index}">${this.options.editText}</button>` : ''}
                        ${this.options.delable ? `<button class="droper-item-delete-btn" data-index="${index}">${this.options.delText}</button>` : ''}
                    `;
                    
                    // 获取图标的位置
                    const rect = iconElement.getBoundingClientRect();
                    const containerRect = this.element.getBoundingClientRect();
                    
                    // 设置编辑面板位置
                    editPanel.style.left = (rect.left - containerRect.left) + 'px';
                    editPanel.style.top = (rect.bottom - containerRect.top) + 'px';
                    
                    // 将编辑面板添加到this.element中
                    this.element.appendChild(editPanel);
                    
                    // 保存当前面板引用
                    currentEditPanel = editPanel;
                    
                    // 显示编辑面板
                    setTimeout(() => {
                        if (editPanel.parentNode) {
                            editPanel.classList.add('show');
                        }
                    }, 0);
                    
                    // 为编辑按钮添加点击事件监听器
                    const editButton = editPanel.querySelector('.droper-item-edit-btn');
                    if (editButton) {
                        editButton.addEventListener('click', (e) => {
                            e.stopPropagation();
                            const index = parseInt(editButton.dataset.index);
                            if (!isNaN(index)) {
                                this.editItem(index);
                            }
                            
                            // 隐藏编辑面板
                            if (currentEditPanel) {
                                currentEditPanel.remove();
                                currentEditPanel = null;
                                currentIconIndex = null;
                            }
                        });
                    }
                    
                    // 为删除按钮添加点击事件监听器
                    const deleteButton = editPanel.querySelector('.droper-item-delete-btn');
                    if (deleteButton) {
                        deleteButton.addEventListener('click', (e) => {
                            e.stopPropagation();
                            const index = parseInt(deleteButton.dataset.index);
                            if (!isNaN(index)) {
                                this.removeItem(index);
                            }
                            
                            // 隐藏编辑面板
                            if (currentEditPanel) {
                                currentEditPanel.remove();
                                currentEditPanel = null;
                                currentIconIndex = null;
                            }
                        });
                    }
                    
                    // 为编辑面板添加鼠标事件监听
                    editPanel.addEventListener('mouseenter', () => {
                        panelHovered = true;
                        if (hidePanelTimer) {
                            clearTimeout(hidePanelTimer);
                            hidePanelTimer = null;
                        }
                    });
                    
                    editPanel.addEventListener('mouseleave', () => {
                        panelHovered = false;
                        // 延迟隐藏面板，给用户时间移动鼠标
                        if (hidePanelTimer) {
                            clearTimeout(hidePanelTimer);
                        }
                        hidePanelTimer = setTimeout(() => {
                            if (!iconHovered && !panelHovered) {
                                if (currentEditPanel) {
                                    currentEditPanel.remove();
                                    currentEditPanel = null;
                                    currentIconIndex = null;
                                }
                            }
                            hidePanelTimer = null;
                        }, 300);
                    });
                }
            }
        });

        // 处理图标鼠标离开事件
        this.menu.addEventListener('mouseout', (e) => {
            const iconElement = e.target.closest('.droper-item-icon');
            if (iconElement) {
                iconHovered = false;
                // 延迟隐藏面板，给用户时间移动鼠标到面板上
                if (hidePanelTimer) {
                    clearTimeout(hidePanelTimer);
                }
                hidePanelTimer = setTimeout(() => {
                    if (!iconHovered && !panelHovered) {
                        if (currentEditPanel) {
                            currentEditPanel.remove();
                            currentEditPanel = null;
                            currentIconIndex = null;
                        }
                    }
                    hidePanelTimer = null;
                }, 300);
            }
        });

        // 外部点击关闭菜单
        document.addEventListener('click', (e) => {
            // 检查点击的元素是否在下拉菜单内
            if (!this.element.contains(e.target)) {
                this.close();
            }
        });

        // ESC键关闭菜单
        document.addEventListener('keydown', (e) => {
            if (e.key === 'Escape') {
                this.close();
            }
        });
    }

    /**
     * 处理菜单项点击
     * @param {Number} index - 菜单项索引
     * @param {Event} e - 事件对象
     */
    _handleItemClick(index, e) {
        // 如果正在编辑，不处理点击事件
        if (e.target.classList.contains('droper-edit-input')) {
            return;
        }

        const item = this.options.data[index];
        if (item) {
            // 保存选中的值
            this.selectedValue = item.value !== undefined ? item.value : item.text;
            // 更新触发器显示
            this.trigger.querySelector('.droper-placeholder').textContent = item.text || this.options.itemText;
            // 更新图标背景颜色
            if (this.options.showIcon) {
                this.trigger.querySelector("."+this.options.itemIcon).style.backgroundColor = item.data.length > 0 ? item.data[0] : '#FFFFFF';
            }
            
            // 移除之前选中项的样式
            const previousSelected = this.menu.querySelector('.droper-menu-item-selected');
            if (previousSelected) {
                previousSelected.classList.remove('droper-menu-item-selected');
                previousSelected.style.removeProperty('--theme-color');
            }
            
            // 为当前选中项添加选中样式
            const currentItem = e.target.closest('.droper-menu-item');
            if (currentItem) {
                currentItem.classList.add('droper-menu-item-selected');
                // 应用主题色
                currentItem.style.setProperty('--theme-color', this.themeColor || this.options.theme || "#409EFF");
            }
            
            // 触发change事件
            this.emit('change', item);
            
            // 执行自定义处理函数
            if (typeof this.options.changeHandler === 'function') {
                this.options.changeHandler(item);
            }
            
            // 关闭菜单（只有在不是编辑或删除操作时才关闭）
            if (!e.target.closest('.droper-item-edit-btn') && 
                !e.target.closest('.droper-item-delete-btn') &&
                !e.target.closest('.droper-edit-confirm') &&
                !e.target.closest('.droper-edit-cancel')) {
                this.close();
            }
        }
    }

    /**
     * 处理创建新项
     */
    _handleCreateItem(e) {
        // 生成唯一的value值
        const uniqueValue = this._generateUniqueValue();
        
        const newItem = {
            text: this.options.itemText+ (this.options.data.length+1),
            icon: this.options.itemIcon,
            value: uniqueValue,
            data:[]
        };

        this.addItem(newItem);
        this.emit('create', newItem);
        
        // 不关闭菜单
        if (e && typeof e.stopPropagation === 'function') {
            e.stopPropagation();
        }
    }

    /**
     * 打开菜单
     */
    open() {
        if (this.isOpen) return;
        
        this.isOpen = true;
        this.menu.classList.add('droper-menu-open');
        this.trigger.classList.add('droper-trigger-active');
        this.emit('open');
    }

    /**
     * 关闭菜单
     */
    close() {
        if (!this.isOpen) return;
        
        this.isOpen = false;
        this.menu.classList.remove('droper-menu-open');
        this.trigger.classList.remove('droper-trigger-active');
        
        // 检查是否有正在编辑的条目，如果有则退出编辑状态
        let hasEditingItems = false;
        this.options.data.forEach((item, index) => {
            if (item._editing) {
                delete item._editing;
                hasEditingItems = true;
            }
        });
        
        // 如果有正在编辑的条目，重新渲染菜单以退出编辑状态
        if (hasEditingItems) {
            this._renderMenu();
        }
        
        this.emit('close');
    }

    /**
     * 切换菜单状态
     */
    toggle() {
        if (this.isOpen) {
            this.close();
        } else {
            this.open();
        }
    }

    /**
     * 更新菜单数据
     * @param {Array} data - 新的菜单数据
     */
    update(data) {
        this.setItems(data);
    }

    /**
     * 设置菜单项
     * @param {Array} data - 菜单数据
     */
    setItems(data) {
        this.options.data = Array.isArray(data) ? data : [];
        
        // 如果数据长度大于0，默认选中第一条数据
        if (this.options.data.length > 0 && this.selectedValue === undefined) {
            const firstItem = this.options.data[0];
            this.selectedValue = firstItem.value !== undefined ? firstItem.value : firstItem.text;
            // 更新触发器显示
            this.trigger.querySelector('.droper-placeholder').textContent = firstItem.text || this.options.itemText;
            // 更新图标背景颜色
            if (this.options.showIcon) {
                this.trigger.querySelector("."+this.options.itemIcon).style.backgroundColor = firstItem.data.length > 0 ? firstItem.data[0] : '#FFFFFF';
            }
        }
        
        this._renderMenu();
    }

    /**
     * 渲染菜单
     */
    _renderMenu() {
        // 清空菜单
        this.menu.innerHTML = '';
        // 如果允许创建，始终显示创建按钮（放在最前）
        if (this.options.creatable) {
            const defaultItem = document.createElement('div');
            defaultItem.className = 'droper-menu-item droper-default-item';
            defaultItem.dataset.index = '-1';
            defaultItem.innerHTML = `
                <i class="${this.options.createIcon}"></i>
                <span>${this.options.createText}</span>
            `;
            this.menu.appendChild(defaultItem);
        }

        // 渲染菜单项
        this.options.data.forEach((item, index) => {
            const menuItem = this._createMenuItem(item, index);
            this.menu.appendChild(menuItem);
        });
        
        // 初始化时应用主题色到已选中项
        this._applyThemeToSelected();
    }

    /**
     * 创建菜单项
     * @param {Object} item - 菜单项数据
     * @param {Number} index - 索引
     * @returns {HTMLElement} 菜单项元素
     */
    _createMenuItem(item, index) {
        const menuItem = document.createElement('div');
        menuItem.className = `droper-menu-item droper-menu-item-${this.options.size}`;
        menuItem.dataset.index = index;
        // 添加value值作为data属性
        if (item.value !== undefined) {
            menuItem.dataset.value = item.value;
        }

        // 检查是否处于编辑状态
        if (item._editing) {
            menuItem.innerHTML = `
                <input type="text" class="droper-edit-input" value="${item.text || ''}" data-index="${index}">
                <div class="droper-edit-actions">
                    <button class="droper-edit-confirm" data-index="${index}">✓</button>
                    <button class="droper-edit-cancel" data-index="${index}">✕</button>
                </div>
            `;
        } else {
            // 检查是否需要显示图标（当editable和delable都为true时）
            const showIcon = this.options.editable && this.options.delable;
            let menuStr = ""
            // 检查是否需要显示图标
            if (this.options.showIcon) {
                menuStr = `
                <i class="${item.icon || this.options.itemIcon}" style="background-color:${item.data.length > 0 ? item.data[0] : '#FFFFFF'}"></i>   
                `;
            }
            menuItem.innerHTML = `
                ${menuStr}
                <span class="droper-item-text">${item.text || this.options.itemText}</span>
                ${showIcon ? `
                <div class="droper-item-icon" data-index="${index}">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
                        <path fill="currentColor" d="M176 416a112 112 0 1 1 0 224 112 112 0 0 1 0-224m336 0a112 112 0 1 1 0 224 112 112 0 0 1 0-224m336 0a112 112 0 1 1 0 224 112 112 0 0 1 0-224"></path>
                    </svg>
                </div>
                ` : `
                <div class="droper-item-actions">
                    ${this.options.editable ? `<button class="droper-item-edit-btn" data-index="${index}">编辑</button>` : ''}
                    ${this.options.delable ? `<button class="droper-item-delete-btn" data-index="${index}">删除</button>` : ''}
                </div>
                `}
            `;
        }

        return menuItem;
    }

    /**
     * 添加菜单项
     * @param {Object} item - 要添加的菜单项
     */
    addItem(item) {
        if (!item || typeof item !== 'object') return;
        
        this.options.data.push(item);
        this._renderMenu();
    }

    /**
     * 删除菜单项
     * @param {Number} index - 要删除的菜单项索引
     */
    removeItem(index) {
        if (index < 0 || index >= this.options.data.length) return;
        
        // 检查删除的条目是否为当前选中条目
        const deletedItem = this.options.data[index];
        const isCurrentSelected = (deletedItem.value !== undefined && this.selectedValue === deletedItem.value) || 
                                 (deletedItem.value === undefined && this.selectedValue === deletedItem.text);
        
        // 从数据中移除
        this.options.data.splice(index, 1);
        
        // 如果删除的是当前选中条目，更新选中状态
        if (isCurrentSelected) {
            // 清除选中值
            this.selectedValue = undefined;
            
            // 更新触发器显示为占位符
            this.trigger.querySelector('.droper-placeholder').textContent = this.options.placeholder;
            
            // 移除选中样式
            const previousSelected = this.menu.querySelector('.droper-menu-item-selected');
            if (previousSelected) {
                previousSelected.classList.remove('droper-menu-item-selected');
                previousSelected.style.removeProperty('--theme-color');
            }
        }
        
        // 重新渲染菜单
        this._renderMenu();
        
        // 触发删除事件
        this.emit('delete', index);
    }
    
    /**
     * 设置选中值
     * @param {*} value - 要设置的值
     */
    setValue(value) {
        // 保存选中的值
        this.selectedValue = value;
        
        // 查找对应的项
        const item = this.options.data.find(item => item.value === value || item.text === value);
        if (item) {
            // 更新触发器显示
            this.trigger.querySelector('.droper-placeholder').textContent = item.text || this.options.itemText;
            // 更新图标颜色
            if (this.options.showIcon) {
                this.trigger.querySelector(this.options.itemIcon).style.color = item.data.length > 0 ? item.data[0] : '#FFFFFF';
            }
            // 触发change事件
            this.emit('change', item);
            
            // 应用主题色到选中项
            this._applyThemeToSelected();
        }
    }

    /**
     * 编辑菜单项
     * @param {Number} index - 要编辑的菜单项索引
     */
    editItem(index) {
        if (index < 0 || index >= this.options.data.length) return;
        
        // 检查是否有其他条目处于编辑状态，如果有则关闭其编辑状态
        let hasOtherEditing = false;
        this.options.data.forEach((item, i) => {
            if (item._editing && i !== index) {
                delete item._editing;
                hasOtherEditing = true;
            }
        });
        
        // 如果有其他条目处于编辑状态，重新渲染菜单
        if (hasOtherEditing) {
            this._renderMenu();
        }
        
        // 设置当前条目的编辑状态
        this.options.data[index]._editing = true;
        
        // 重新渲染菜单
        this._renderMenu();
        
        // 聚焦到输入框
        setTimeout(() => {
            const input = this.menu.querySelector(`.droper-edit-input[data-index="${index}"]`);
            if (input) {
                input.focus();
                input.select();
            }
        }, 0);
        
        // 触发编辑事件
        this.emit('edit', { item: this.options.data[index], index });
    }

    /**
     * 确认编辑
     * @param {Number} index - 菜单项索引
     */
    _confirmEdit(index) {
        if (index < 0 || index >= this.options.data.length) return;
        
        const input = this.menu.querySelector(`.droper-edit-input[data-index="${index}"]`);
        if (input) {
            // 获取编辑前的值
            const oldValue = this.options.data[index].value;
            const oldText = this.options.data[index].text;
            
            // 更新数据
            this.options.data[index].text = input.value;
            // 清除编辑状态
            delete this.options.data[index]._editing;
            
            // 检查当前条目是否为选中条目，如果是则更新当前选中的文字
            if ((oldValue !== undefined && this.selectedValue === oldValue) || 
                (oldValue === undefined && this.selectedValue === oldText)) {
                // 更新触发器显示
                this.trigger.querySelector('.droper-placeholder').textContent = input.value;
                // 如果有value，则保持value不变，否则更新selectedValue为新的text
                if (oldValue === undefined) {
                    this.selectedValue = input.value;
                }
            }
            
            // 重新渲染
            this._renderMenu();
        }
    }

    /**
     * 取消编辑
     * @param {Number} index - 菜单项索引
     */
    _cancelEdit(index) {
        if (index < 0 || index >= this.options.data.length) return;
        
        // 清除编辑状态
        delete this.options.data[index]._editing;
        
        // 重新渲染
        this._renderMenu();
    }

    /**
     * 绑定事件监听器
     * @param {String} event - 事件名称
     * @param {Function} handler - 事件处理函数
     */
    on(event, handler) {
        if (!this.events[event]) {
            this.events[event] = [];
        }
        this.events[event].push(handler);
    }

    /**
     * 触发事件
     * @param {String} event - 事件名称
     * @param {any} data - 事件数据
     */
    emit(event, data) {
        if (this.events[event]) {
            this.events[event].forEach(handler => {
                handler(data);
            });
        }
    }

    /**
     * 销毁组件
     */
    destroy() {
        // 移除事件监听器
        document.removeEventListener('click', this.close);
        document.removeEventListener('keydown', this.close);
        
        // 清空DOM
        this.element.innerHTML = '';
        
        // 清空引用
        this.element = null;
        this.trigger = null;
        this.menu = null;
        this.events = {};
    }
}
